import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_pagewise/flutter_pagewise.dart';
import 'package:loxen/mode/base_mode.dart';
import 'package:loxen/mode/order_list_mode.dart';
import 'package:loxen/utils/color.dart';
import 'package:loxen/utils/time_util.dart';
import 'package:loxen/view/material/material_order_receive/order_detail_widget.dart';
import 'package:loxen/widget/my_subassembly.dart';
import 'package:rxdart/rxdart.dart';
import 'package:loxen/api/api.dart';
import 'package:loxen/mode/order_detail_mode.dart';
import 'package:loxen/utils/app_enum_util.dart';
import 'package:loxen/viewmode/base_view_model.dart';
import 'package:loxen/widget/empty_widget.dart';
import 'package:loxen/widget/fail_widget.dart';
import 'package:loxen/widget/loading_widget.dart';
import 'package:provider/provider.dart';

class _ViewModel extends BaseViewModel {
  StaffType staffType;
  int pageSize = 7;

  Map<String, List<OrderDetailMode>> map = {};

  _ViewModel(this.staffType);

  String getMode() {
    switch (staffType) {
      case StaffType.ALL:
        return '0';
      case StaffType.SAMPLE_TO_BE_PREPARED:
        return '1';
      case StaffType.SAMPLE_TO_BE_SENT:
        return '2';
      case StaffType.COMPLETED:
        return '3';
    }
    return '0';
  }

  void loadData() {
    ApiService.schedule(getMode(), page: '1', pageSize: pageSize.toString())
        .doOnListen(() {
          mState = BaseState.LOADING;
          notifyListeners();
        })
        .flatMap((value) => compute(decodeOrderList, value.data).asStream())
        .flatMap((value) => Stream.value(value?.data))
        .listen((event) {
          if (event != null) {
            map.putIfAbsent('0', () => event.results);
            mState = BaseState.CONTENT;
          } else {
            mState = BaseState.FAIL;
          }
        }, onError: (error, stack) {
          mState = BaseState.FAIL;
        }, onDone: () => notifyListeners());
  }

  Future<List<OrderDetailMode>> nextData(int index) async {
    if (map.containsKey('$index')) {
      return map['$index'];
    } else {
      var data =
          await ApiService.schedule(getMode(), page: '${index + 1}', pageSize: pageSize.toString())
              .flatMap((value) => compute(decodeOrderList, value.data).asStream())
              .flatMap((value) => Stream.value(value?.data))
              .flatMap((value) => Stream.value(value.results))
              .first;
      map.putIfAbsent('$index', () => data);
      return data;
    }
  }

  static BaseMode<StaffOrderList> decodeOrderList(dynamic json) {
    return BaseMode<StaffOrderList>(json);
  }
}

class StaffOrderListPage extends StatefulWidget {
  final StaffType staffType;

  const StaffOrderListPage({Key key, this.staffType}) : super(key: key);

  @override
  _StaffOrderListPageState createState() => _StaffOrderListPageState();
}

class _StaffOrderListPageState extends State<StaffOrderListPage>
    with AutomaticKeepAliveClientMixin {
  PagewiseLoadController pageLoadController;

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return ChangeNotifierProvider<_ViewModel>(
      create: (BuildContext context) {
        var model = _ViewModel(widget.staffType);
        model.loadData();
        pageLoadController = PagewiseLoadController<OrderDetailMode>(
            pageFuture: model.nextData, pageSize: model.pageSize);
        return model;
      },
      child: Builder(
        builder: (BuildContext context) {
          var state = context.select<_ViewModel, BaseState>((value) => value.mState);
          Widget page;
          switch (state) {
            case BaseState.LOADING:
              page = LoadingWidget();
              break;
            case BaseState.FAIL:
              page = FailWidget();
              break;
            case BaseState.EMPTY:
            case BaseState.CONTENT:
              page = PagewiseListView<OrderDetailMode>(
                addAutomaticKeepAlives: false,
                loadingBuilder: (_) => MySubassembly.getLoadingItem(),
                noItemsFoundBuilder: (_) => MySubassembly.getNullItem(),
                itemBuilder: (context, entity, index) {
                  return createCard(context, entity);
                },
                pageLoadController: pageLoadController,
              );
              break;
          }
          return RefreshIndicator(
            onRefresh: () async {
              context.read<_ViewModel>().map.clear();
              pageLoadController.reset();
              return true;
            },
            child: page,
          );
        },
      ),
    );
  }

  @override
  bool get wantKeepAlive => true;

  Widget createCard(BuildContext context, OrderDetailMode entity) {
    return Container(
      padding: EdgeInsets.only(top: 16.h, right: 20.w, left: 20.w),
      child: Card(
        elevation: 5,
        child: _itemWidget(entity),
      ),
    );
  }

  Widget _itemWidget(OrderDetailMode orderDetailMode) {
    String imagePath;
    if (orderDetailMode.mode == '1') {
      imagePath = 'images/tongcheng.png';
    } else if (orderDetailMode.mode == '2') {
      imagePath = 'images/daodian.png';
    } else {
      imagePath = 'images/kuaidi.png';
    }
    return InkWell(
      onTap: () => Navigator.of(context).push(MaterialPageRoute(
          builder: (_) => OrderDetailWidget(id: orderDetailMode.id.toString(), staff: true))),
      child: Container(
        margin: EdgeInsets.only(top: 30.h, bottom: 30.h),
        padding: EdgeInsets.only(left: 20.w, right: 20.w),
        height: 100.h,
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Image.asset(
              imagePath,
              width: 80.h,
              height: 80.h,
            ),
            Expanded(
              child: Padding(
                padding: EdgeInsets.only(left: 20.w, top: 10.h),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      orderDetailMode.getMode(),
                      style: TextStyle(
                        fontSize: 28.sp,
                        color: Colours.main_text,
                      ),
                    ),
                    Text(
                      TimeUtil.getStringTime2(orderDetailMode.startTime, orderDetailMode.endTime),
                      style: TextStyle(
                        fontSize: 24.sp,
                        color: Colours.main_text,
                      ),
                    )
                  ],
                ),
              ),
            ),
            Container(
              child: Center(
                child: Row(
                  children: [
                    Text(
                      orderDetailMode.getState(),
                      style: TextStyle(
                        fontSize: 24.sp,
                        color: Colours.app_main,
                      ),
                    ),
                    Image.asset(
                      'images/mine_right.png',
                      width: 30.w,
                      height: 40.h,
                    ),
                  ],
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}
